package com.jwsoft.manager.core.integration.impl;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.bifang.engine.assistant.core.annotation.ApiService;
import com.bifang.engine.assistant.core.annotation.OpApi;
import com.bifang.engine.assistant.core.annotation.SaveOplog;
import com.bifang.engine.assistant.core.enums.AuTypeEnum;
import com.bifang.engine.assistant.core.enums.AuthStatusEnum;
import com.bifang.engine.assistant.core.enums.BoolEnum;
import com.bifang.engine.assistant.core.enums.FuncTypeEnum;
import com.bifang.engine.assistant.core.exception.AppException;
import com.bifang.engine.assistant.core.utils.SessionUtil;
import com.bifang.engine.cache.redis.RedisHelper;
import com.bifang.module.base.core.helper.DictHelper;
import com.bifang.module.base.core.integration.DictIntegration;
import com.jwsoft.manager.common.enums.CardTypeEnum;
import com.jwsoft.manager.common.enums.EnrollStatusFormalEnum;
import com.jwsoft.manager.common.enums.SchoolNatureEnum;
import com.jwsoft.manager.common.enums.TjTypeEnum;
import com.jwsoft.manager.common.vo.eduSchool.EduSchoolVO;
import com.jwsoft.manager.common.vo.eduSchoolConfig.EduSchoolConfigVO;
import com.jwsoft.manager.common.vo.eduSchoolTj.StudentEnrollTjVO;
import com.jwsoft.manager.common.vo.eduSyncJhApply.EduSyncJhApplyVO;
import com.jwsoft.manager.common.vo.eduSyncJhApprove.EduSyncJhApproveVO;
import com.jwsoft.manager.common.vo.eduSyncJhDelete.EduSyncExistInfo;
import com.jwsoft.manager.common.vo.eduSyncJhDelete.EduSyncJhDeleteQueryVO;
import com.jwsoft.manager.common.vo.eduSyncJhEnroll.EduSyncJhEnrollVO;
import com.jwsoft.manager.core.dao.model.EduSchool;
import com.jwsoft.manager.core.dao.model.EduStudentEnroll;
import com.jwsoft.manager.core.dao.model.EduStudentTj;
import com.jwsoft.manager.core.dao.service.*;
import com.jwsoft.manager.core.integration.*;
import com.jwsoft.manager.core.util.EduEnrollClearCacheHelper;
import com.jwsoft.manager.core.util.EduHelper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 学校调剂参数管理业务实现类
 *
 * @author chenzh
 * @since 2023-07-04
 */
@ApiService(funcCode = "eduSchoolTjParams", title = "学校调剂参数管理")
public class EduSchoolTjParamsJhIntegrationImpl implements EduSchoolTjParamsJhIntegration {
    @Autowired
    private EduSchoolService eduSchoolService;
    @Autowired
    public EduSchoolTjParamsService eduSchoolTjParamsService;
    @Autowired
    private EduHelper eduHelper;
    @Autowired
    private DictHelper dictHelper;
    @Autowired
    private EduStudentEnrollService eduStudentEnrollService;
    @Autowired
    private EduStudentTjService eduStudentTjService;
    @Autowired
    private EduSyncJhDeleteService eduSyncJhDeleteService;
    @Autowired
    private RedisHelper redisHelper;
    @Autowired
    private DictIntegration dictIntegration;
    @Autowired
    private EduSyncJhApplyIntegration applyIntegration;
    @Autowired
    private EduSyncJhApproveIntegration approveIntegration;
    @Autowired
    private EduSyncJhEnrollIntegration enrollIntegration;
    @Autowired
    private EduEnrollClearCacheHelper eduEnrollClearCacheHelper;
    @Override
    @OpApi(funcCode = "eduSchoolTjParamsJh0008", title = "义务教育管理员统筹分流保存", funcType = FuncTypeEnum.insert)
    @SaveOplog(
            operationType = "eduSchoolTjParamsJh0008",
            operationName = "义务教育管理员统筹分流保存",
            dataType = "studentEnrollId",
            auType = AuTypeEnum.OTHER)
    @Transactional
    public void schoolTj(StudentEnrollTjVO vo) {
        if (StringUtils.isBlank(vo.getStudentEnrollId())) {
            throw new AppException("报名id不能为空");
        }
        if (StringUtils.isBlank(vo.getSchoolId())) {
            throw new AppException("统筹分流目标学校不能为空");
        }
        EduStudentEnroll enroll = eduStudentEnrollService.getById(vo.getStudentEnrollId());
        if (enroll == null) {
            throw new AppException("报名信息不存在");
        }
        String formSchoolId=enroll.getSchoolId();
        String formSchoolName=enroll.getSchoolName();
        if (EnrollStatusFormalEnum.xtblq.getType().equals(enroll.getEnrollStatus())) {
            throw new AppException("报名无效学生不能统筹分流");
        }
        if (AuthStatusEnum.NO.getType().equals(enroll.getAuthStatus())) {
            throw new AppException("审核不通过学生不能统筹分流");
        }
        if (!EnrollStatusFormalEnum.lq.getType().equals(enroll.getEnrollStatus())){
            if(!EnrollStatusFormalEnum.fs.getType().equals(enroll.getEnrollStatus())){
                throw new AppException("复审不通过学生不能统筹分流");
            }
        }
        EduSchool mbSchool = eduSchoolService.getById(vo.getSchoolId());
        if (enroll.getSchoolId().equals(mbSchool.getOrgId())){
            throw new AppException("目标学校不能与报名学校相同");
        }
        QueryWrapper<EduStudentTj> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(EduStudentTj::getStudentEnrollId, vo.getStudentEnrollId())
                .eq(EduStudentTj::getFromSchoolId, enroll.getSchoolId())
                .eq(EduStudentTj::getCurrentFlag, BoolEnum.TRUE.getType());
        EduStudentTj eduStudentCheck = eduStudentTjService.getOne(queryWrapper, false);
        if (eduStudentCheck != null) {
            if (AuthStatusEnum.NODO.getType().equalsIgnoreCase(eduStudentCheck.getAuthStatus())) {
                throw new AppException("家长已申请统筹分流，不能直接统筹分流，请通过审核功能操作");
            }
            eduStudentCheck.setCurrentFlag(BoolEnum.FALSE.getType());
            eduStudentTjService.updateById(eduStudentCheck);
        }
        //判断是否超过计划数
        EduSchoolVO eduSchool = eduSchoolService.getDetail(mbSchool.getOrgId());
        QueryWrapper<EduStudentEnroll> enrollQueryWrapper = new QueryWrapper<>();
        enrollQueryWrapper.lambda().eq(EduStudentEnroll::getEnrollStatus, EnrollStatusFormalEnum.lq.getType())
                .eq(EduStudentEnroll::getSchoolId, mbSchool.getOrgId())
                .eq(EduStudentEnroll::getYear, enroll.getYear());
        long lqrs = eduStudentEnrollService.count(enrollQueryWrapper);
        if (!CollectionUtils.isEmpty(eduSchool.getConfigList())) {
            EduSchoolConfigVO configVO = eduSchool.getConfigList().get(0);
            Integer jhs = configVO.getEnrolment() == null ? 0 : configVO.getEnrolment();
            if (jhs - lqrs <= 0) {
                throw new AppException("目标学校已超计划数，不能统筹分流");
            }
        }
        //调剂
        if (StringUtils.isBlank(enroll.getFromSchoolId())) {
            //调出学校记录的是报名时候的学校
            enroll.setFromSchoolId(formSchoolId);
            enroll.setFromSchoolName(formSchoolName);
        }
        if (mbSchool.getSchoolNature().equals(SchoolNatureEnum.mzg.getType())
                && enroll.getSchoolNature().equals(SchoolNatureEnum.gb.getType())){
            //目标学校为民转公学校，但是调出学校为公办学校
            //设置：招生计划类别
            enroll.setConfigTypeName("民转公");
            //设置招生类别 和别名
            if (enroll.getConfigName().equals("A") || enroll.getConfigName().equals("B")){
                //A B 设置为户籍
                enroll.setConfigName("户籍");
                enroll.setConfigNameAlias("户籍");
            }else {
                //其他设置为房产
                enroll.setConfigName("房产");
                enroll.setConfigNameAlias("房产");
            }
        } else if (mbSchool.getSchoolNature().equals(SchoolNatureEnum.gb.getType())
                && enroll.getSchoolNature().equals(SchoolNatureEnum.mzg.getType())) {
            //目标学校为公办学校，但是调出学校为民转公学校
            enroll.setConfigTypeName("公办");
            enroll.setConfigName("A");
            enroll.setConfigNameAlias("房户一致（正学区）");
        }
        enroll.setSchoolNature(mbSchool.getSchoolNature());
        enroll.setSchoolId(eduSchool.getOrgId());
        enroll.setSchoolName(eduSchool.getSchoolName());
        enroll.setStreet(eduSchool.getStreet());
        enroll.setEnrollStatus(EnrollStatusFormalEnum.lq.getType());
        enroll.setAdmitFlag(BoolEnum.TRUE.getType());
        enroll.setAdmitRemarks("统筹分流录取");
        enroll.setAdmitTime(new Date());
        enroll.setDeployFlag(BoolEnum.TRUE.getType());
        enroll.setBasis("从" + formSchoolName + "统筹分流到" + mbSchool.getSchoolName());
        enroll.setApplyId(this.getApplyId(enroll.getYear(), eduSchool.getSchoolNature(), eduSchool.getSchoolNum(), 97, eduSchool.getOrgId(), 1));
        eduStudentEnrollService.updateById(enroll);
        EduStudentTj eduStudentTj = new EduStudentTj();
        eduStudentTj.setStudentTjId(IdUtil.simpleUUID());
        eduStudentTj.setStudentEnrollId(enroll.getStudentEnrollId());
        eduStudentTj.setFullName(enroll.getFullName());
        eduStudentTj.setIdcard(enroll.getIdcard());
        eduStudentTj.setFromSchoolId(formSchoolId);
        eduStudentTj.setFromSchoolName(formSchoolName);
        eduStudentTj.setToSchoolId(mbSchool.getOrgId());
        eduStudentTj.setToSchoolName(mbSchool.getSchoolName());
        eduStudentTj.setYear(enroll.getYear());
        eduStudentTj.setCurrentFlag(BoolEnum.TRUE.getType());
        eduStudentTj.setAreaCode(enroll.getAreaCode());
        eduStudentTj.setAuthStatus(AuthStatusEnum.YES.getType());
        eduStudentTj.setTjType(TjTypeEnum.xx.getType());
        eduStudentTj.setConfigName(enroll.getConfigName());
        eduStudentTj.setConfigTypeName(enroll.getConfigTypeName());
        eduStudentTj.setRegisterDate(enroll.getRegisterDate());
        eduStudentTj.setQysj(enroll.getQysj());
        eduStudentTj.setCbTotal(enroll.getCbTotal());
        eduStudentTj.setStudentEnrollStatus(enroll.getEnrollStatus());
        eduStudentTj.setStudentAuthStatus(enroll.getAuthStatus());
        eduStudentTj.setStudentAdmitFlag(enroll.getAdmitFlag());
        eduStudentTjService.save(eduStudentTj);

        //需要调用查询接口，判断其他区县是否有录取数据
        EduSyncJhDeleteQueryVO queryVO = new EduSyncJhDeleteQueryVO();
        queryVO.setIdcard(enroll.getIdcard());
        queryVO.setName(enroll.getFullName());
        queryVO.setApplyCountyCode(enroll.getAreaCode());
        EduSyncExistInfo eduSyncExistInfo = eduSyncJhDeleteService.querySyncInfo(queryVO);
        if (eduSyncExistInfo != null && "3".equals(eduSyncExistInfo.getType())) {
            //如果返回结果不为空并且是录取状态 判断行政区划是否为当前区县;
            if (!enroll.getAreaCode().equals(eduSyncExistInfo.getApplyCountyCode())) {
                //如果不是当前区县，不能进行处理
                throw new AppException("该学生以被"+eduSyncExistInfo.getApplyCountyName()+"教育局录取！");
            }
        }

        //同步报名表，审核表，录取表
        //复审通过
        // 1.同步报名数据
        EduSyncJhApplyVO applyVO = new EduSyncJhApplyVO();
        applyVO.setYear(enroll.getYear());
        applyVO.setSchoolCategory(enroll.getSchoolCategory());;
        applyVO.setCardType(enroll.getCardType());
        applyVO.setName(enroll.getFullName());
        applyVO.setIdcard(enroll.getIdcard());
        applyVO.setSex(enroll.getSex());
        applyVO.setHouseholdAddress(enroll.getHouseholdPlace());
        applyVO.setResidentialAddress(enroll.getAddress());
        if (StringUtils.isNotBlank(enroll.getFatherIdcard())){
            applyVO.setMasterGuardianNumber(enroll.getFatherIdcard());
            applyVO.setMasterGuardianName(enroll.getFatherName());
            applyVO.setMasterGuardianRelation("1");
        }
        if (StringUtils.isNotBlank(enroll.getMotherIdcard())){
            applyVO.setSlaveGuardianNumber(enroll.getMotherIdcard());
            applyVO.setSlaveGuardianName(enroll.getMotherName());
            applyVO.setSlaveGuardianRelation("2");
        }
        applyVO.setApplyCountyCode(enroll.getAreaCode());
        //当前时间戳
        applyVO.setApplyTime(System.currentTimeMillis());
        if (!applyVO.getCardType().equals(CardTypeEnum.idcard)){
            if (applyVO.getSex().equals("1")){
                applyVO.setSex("0");
            }else if (applyVO.getSex().equals("2")){
                applyVO.setSex("1");
            }
        }
        try {
            applyIntegration.saveSyncApplyInfo2(applyVO);
        }catch (AppException e){
            throw new AppException(e.getMessage());
        }catch (Exception e){
            throw new AppException(e.getMessage());
        }

        //2.同步审核表数据
        EduSyncJhApproveVO syncJhApproveVO = new EduSyncJhApproveVO();
        syncJhApproveVO.setSchoolCategory(enroll.getSchoolCategory());
        syncJhApproveVO.setApproveState(AuthStatusEnum.YES.getType());
        syncJhApproveVO.setApproveTime(new Date());
        syncJhApproveVO.setApproveHuman(SessionUtil.getUserId());
        syncJhApproveVO.setCardType(enroll.getCardType());
        syncJhApproveVO.setName(enroll.getFullName());
        syncJhApproveVO.setIdcard(enroll.getIdcard());
        syncJhApproveVO.setApplyCountyCode(enroll.getAreaCode());
        syncJhApproveVO.setApproveOpinion(enroll.getAuthRemarks());
        try {
            approveIntegration.saveSyncApproveInfo2(syncJhApproveVO);
        }catch (AppException e){
            throw new AppException(e.getMessage());
        }catch (Exception e){
            throw new AppException(e.getMessage());
        }

        //3.同步录取表数据
        EduSyncJhEnrollVO syncJhEnrollVO = new EduSyncJhEnrollVO();
        syncJhEnrollVO.setSchoolCategory(enroll.getSchoolCategory());
        syncJhEnrollVO.setCardType(enroll.getCardType());
        syncJhEnrollVO.setName(enroll.getFullName());
        syncJhEnrollVO.setIdcard(enroll.getIdcard());
        syncJhEnrollVO.setEnrollState(AuthStatusEnum.YES.getType());
        syncJhEnrollVO.setEnrollHuman(SessionUtil.getUserId());
        syncJhEnrollVO.setEnrollTime(new Date());
        syncJhEnrollVO.setEnrollSchoolName(enroll.getSchoolName());
        syncJhEnrollVO.setEnrollSchoolCode(enroll.getSchoolId());
        syncJhEnrollVO.setApplyCountyCode(enroll.getAreaCode());
        syncJhEnrollVO.setEnrollOpinion(enroll.getAuthRemarks());
        enrollIntegration.saveSyncEnrollInfo2(syncJhEnrollVO);
        eduEnrollClearCacheHelper.clearCacheMyEnroll(enroll.getIdcard());
        eduEnrollClearCacheHelper.clearCacheMyEnroll(enroll.getFatherIdcard());
        eduEnrollClearCacheHelper.clearCacheMyEnroll(enroll.getMotherIdcard());

    }

    @Override
    @OpApi(funcCode = "eduSchoolTjParamsJh0007", title = "根据学校id查询可调剂学校信息", funcType = FuncTypeEnum.query, checkPrivilege = BoolEnum.FALSE)
    public List<EduSchoolVO> getListBySchoolId(EduSchoolVO vo) {
        if (StringUtils.isBlank(vo.getOrgId())) {
            throw new AppException("学校id为空");
        }
        EduSchool school = eduSchoolService.getById(vo.getOrgId());
        if (school==null){
            throw new AppException("学校不存在");
        }
        List<String> natureList = new ArrayList<>();
        if (school.getSchoolNature().equals(SchoolNatureEnum.gb.getType()) || school.getSchoolNature().equals(SchoolNatureEnum.mzg.getType())){
            natureList.add(SchoolNatureEnum.gb.getType());
            natureList.add(SchoolNatureEnum.mzg.getType());
        }else{
            natureList.add(SchoolNatureEnum.mb.getType());
        }
        LambdaQueryWrapper<EduSchool> wrapper = new QueryWrapper<EduSchool>().lambda()
                .ne(EduSchool::getOrgId, school.getOrgId())
                .eq(EduSchool::getAreaCode,school.getAreaCode())
                .in(EduSchool::getSchoolNature,natureList)
                .eq(EduSchool::getStatus,BoolEnum.TRUE.getType())
                .eq(EduSchool::getRecruitStatus,BoolEnum.FALSE.getType())
                .eq(EduSchool::getSchoolCategory,school.getSchoolCategory());
        List<EduSchool> schoolList = eduSchoolService.list(wrapper);
        return Convert.toList(EduSchoolVO.class,schoolList);
    }


    public  String getApplyId(Integer year,String schoolNature,String schoolNum,Integer orderNo,String shcoolId,Integer count){
        if(count==null){
            count=count+1;
        }
        if(count>10){
            //超过10次未能比对到不重复的数据，返回报错
            throw new AppException("系统繁忙，请重新点提交");
        }
        String y=year % 100+"";
        String num = StringUtils.leftPad(schoolNum, 9,"0");
        String orderNoId = StringUtils.leftPad(orderNo + "", 2, "0");
        String applyId=y+num+orderNoId;
        if("0".equals(schoolNature)){
            String redisKey="ywEnroll:gb:"+shcoolId+":"+orderNo;
            if(redisHelper.hasKey(redisKey)) {
                String redisApplyId= (String) redisHelper.get(redisKey);
                applyId=String.valueOf(Long.parseLong(redisApplyId)+1);
                redisHelper.set(redisKey,applyId,86400);
            }else{
                //公办
                String max=eduStudentEnrollService.queryMaxApplyId(applyId,shcoolId,year);
                if(StringUtils.isBlank(max)){
                    applyId=applyId+StringUtils.leftPad("1",4, "0");
                }else{
                    applyId=String.valueOf(Long.parseLong(max)+1);
                }
                redisHelper.set(redisKey,applyId,86400);
            }
            return applyId;
        }else{
            //民办或者公参民转公
            String redisKey="ywEnroll:mb:"+shcoolId+":"+orderNo;
            Integer randomId =null;
            if(redisHelper.hasKey(redisKey)) {
                List<Integer> randomList= (List<Integer>) redisHelper.get(redisKey);
                if(CollectionUtils.isEmpty(randomList)){
                    Integer[] randomNums= NumberUtil.generateBySet(1,9999,3000);
                    randomList= Arrays.stream(randomNums).distinct().collect(Collectors.toList());
                    randomId=randomList.get(0);
                    randomList.remove(randomId);
                    redisHelper.set(redisKey,randomList,259200);
                }else{
                    randomId=randomList.get(0);
                    randomList.remove(randomId);
                    redisHelper.set(redisKey,randomList,259200);
                }
            }else{
                Integer[] randomNums=NumberUtil.generateBySet(1,9999,3000);
                List<Integer> randomList=Arrays.stream(randomNums).distinct().collect(Collectors.toList());
                randomId=randomList.get(0);
                randomList.remove(randomId);
                redisHelper.set(redisKey,randomList,259200);
            }
            applyId=applyId+StringUtils.leftPad(randomId + "", 4, "0");

        }
        QueryWrapper<EduStudentEnroll> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().select(EduStudentEnroll::getStudentEnrollId).eq(EduStudentEnroll::getSchoolId,shcoolId)
                .eq(EduStudentEnroll::getYear,year)
                .eq(EduStudentEnroll::getApplyId,applyId);
        if(eduStudentEnrollService.count(queryWrapper)>0){
            applyId=this.getApplyId(year,schoolNature,schoolNum,orderNo,shcoolId,count);
        }
        return applyId;
    }

}
